﻿using HuaCheng.Controller;
using HuaCheng.DataAccess;
using HuaCheng.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections.Concurrent;
using System.Text;
using System.Net.NetworkInformation;


namespace HuaCheng.SendAndReceive
{
    /// <summary>
    /// 启动监听类
    /// </summary>
    public class StartListen
    {
        //检测发送数据线程是否结束
        private ConcurrentDictionary<string, bool> isSendThreadOverDic = new ConcurrentDictionary<string, bool>();
        //用作连接对象asyState的id标志
        private int connectCount = 0;
        //设置接收缓冲区大小
        private int BufferSize = 64 * 1024;
        //建立一个与缓冲区数据有关的实例
        public ConcurrentDictionary<string, AnalysicBufferModel> analysicBufferModelDic = new ConcurrentDictionary<string, AnalysicBufferModel>();
        //定义一个安全字典用来保存当前客户端的连接状态
        public ConcurrentDictionary<string, bool> isConnected = new ConcurrentDictionary<string, bool>();
        //socket服务
        static public Socket server;
        //增加日志记录
        log4net.ILog log = log4net.LogManager.GetLogger("Huacheng.Logging");

        //记录每个中位机当前处理的包序
        public static ConcurrentDictionary<string, int> preSeq = new ConcurrentDictionary<string, int>();

        //当前每个中位机处理的包序
        public static ConcurrentDictionary<string, int> currSeq = new ConcurrentDictionary<string, int>();


        //存储客户端信息的字典
        public static ConcurrentDictionary<string, Socket> clientDic = new ConcurrentDictionary<string, Socket>();
        //独立模式动作包
        CommandProtocol.IndependAction inAction = new CommandProtocol.IndependAction();
        //并联模式动作包
        CommandProtocol.ParalleAction paAction = new CommandProtocol.ParalleAction();
        public byte[] temp;
        public bool[] isClosed = new bool[8];
        public bool[] isCloseJudge = new bool[8];
        public bool[] isChannelParalle = new bool[8];
        public int stepNum;
        public int gid;

        //保存endReceive接收超时状态
        public ConcurrentDictionary<string, bool> isOverDelayDic = new ConcurrentDictionary<string, bool>();
        //判断各客户端是否连接的定时器(依据endReceive接收是否超时)
        public ConcurrentDictionary<string, System.Timers.Timer> timerConnectDic = new ConcurrentDictionary<string, System.Timers.Timer>();
        //判断网线是否有重新接入的定时器
        public ConcurrentDictionary<string, System.Timers.Timer> timerNetContionDic = new ConcurrentDictionary<string, System.Timers.Timer>();
        //待发送数据用的队列
        public static ConcurrentDictionary<string, ConcurrentQueue<SendInfo>> queSendDic = new ConcurrentDictionary<string, ConcurrentQueue<SendInfo>>();

        //接受数据用的队列
        //public static ConcurrentDictionary<string, ConcurrentQueue<string>> queReceiveDic = new ConcurrentDictionary<string, ConcurrentQueue<string>>();


        //状态包处理的事件和委托
        public delegate void ReceiveData(byte[] bytes, string ip);
        public static event ReceiveData ReceiveChannelData;
        public void OnReceiveChannelData(byte[] bytes, string ip)
        {
            if (ReceiveChannelData != null)
            {
                ReceiveChannelData(bytes, ip);
            }
        }
        //工况请求包处理的事件、委托和方法
        public delegate void ReceiveCondiReq(CondiRequest condiReq, string ip);
        public static event ReceiveCondiReq ReceiveCondiRequest;

        //关机菜单的委托和事件
        public delegate void UserClose(int realid, string ip, bool isMove);
        public static event UserClose CloseByUser;

        //网络断开的委托和事件
        public delegate void NetClose(string ip);
        public static event NetClose NetDisConnect;

        //网络断开事件
        public void OnNetClose(string ip)
        {
            if (NetDisConnect != null)
            {
                NetDisConnect(ip);
            }
        }

        //用户关闭事件
        public void OnUserClose(int realid, string ip, bool isMove)
        {
            if (CloseByUser != null)
            {
                CloseByUser(realid, ip, isMove);
            }
        }
        public void OnReceiveCondiRequest(CondiRequest condiReq, string ip)
        {
            if (ReceiveCondiRequest != null)
            {
                ReceiveCondiRequest(condiReq, ip);
            }
        }
        //定义一个内部类 传递参数到主程序
        public class CloseConnectEventArgs : EventArgs
        {
            public readonly string connIp;//客户端ip
            public readonly string connDevType;//客户端设备类型
            public readonly bool connStat;//连接状态
            public CloseConnectEventArgs(string ip, string type, bool conn)
            {
                this.connIp = ip;
                this.connDevType = type;
                this.connStat = conn;
            }
        }
        //定义一个内部类 传递参数到主程序
        public class ConnectEventArgs : EventArgs
        {
            public readonly string connIp;//客户端ip
            public readonly string connDevType;//客户端设备类型
            public readonly bool connStat;//连接状态
            public ConnectEventArgs(string ip, string type, bool conn)
            {
                this.connIp = ip;
                this.connDevType = type;
                this.connStat = conn;
            }
        }
        //声明委托
        public delegate void CloseConnectEventHandler(Object sender, CloseConnectEventArgs e);
        //声明断开连接事件
        public event CloseConnectEventHandler CloseConnect;
        //声明委托
        public delegate void ConnectEventHandler(Object sender, ConnectEventArgs e);
        //声明新连接事件
        public event ConnectEventHandler NewConnect;
        //新建连接监听方法
        public virtual void OnNewConnect(ConnectEventArgs e)
        {
            if (NewConnect != null)
            {
                NewConnect(this, e);
            }
        }
        //断开连接监听方法
        public virtual void OnCloseConnect(CloseConnectEventArgs e)
        {
            if (CloseConnect != null)
            {
                CloseConnect(this, e);
            }
        }
        //
        /// <summary>
        /// 建立Socket连接，接收客户端信息
        /// </summary>
        public void Connected()
        {
            try
            {
                //从数据库字典表中获取服务器的ip和port，即中位机程序所在的ip地址和port
                IPAddress local = IPAddress.Parse(DicHelper.RetrieveIPPath());
                IPEndPoint iep = new IPEndPoint(local, Convert.ToInt32(DicHelper.RetrievePort()));

                //新建Socket通信
                server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                server.Bind(iep);
                server.Listen(1024);
                //开启异步操作尝试连接
                server.BeginAccept(new AsyncCallback(CallbackAccept), server);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.StackTrace + e.Message);
            }
        }
        /// <summary>
        /// 循环查询发送队列，如果有数据存在就执行发送操作
        /// </summary>
        /// <param name="state"></param>
        public void SendMessage(object state)
        {
            string ip = (string)state;
            while (server != null && clientDic[ip] != null)
            {
                try
                {
                    if (queSendDic[ip].Count > 0)
                    {
                        SendInfo sendInfo = null;
                        if (queSendDic[ip].TryDequeue(out sendInfo))
                        {
                            TcpControl.Send(sendInfo.temp, sendInfo.client, ip);
                        }
                    }
                    else
                    {
                        Thread.Sleep(10);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.StackTrace + e.Message);
                }
            }
            isSendThreadOverDic[ip] = true;//表示当前线程结束
        }
        /// <summary>
        /// 循环查询接收队列，如果有数据存在就对数据进行处理
        /// </summary>
        /// <param name="state"></param>
        //public void ReceiveMessage(object state)
        //{
        //    string ip = (string)state;
        //    while (server != null && clientDic[ip] != null)
        //    {
        //        try
        //        {
        //            if (queReceiveDic[ip] != null)
        //            {
        //                string data = null;
        //                if (queReceiveDic[ip].TryDequeue(out data))
        //                {
        //                    if (data != null)
        //                    {
        //                        string[] str = data.Split(new char[] { ':' });
        //                        byte[] bufferData = Convert.FromBase64String(str[0]);
        //                        ProcessData(bufferData, str[1], str[2]);
        //                    }
        //                }
        //            }
        //            else
        //            {
        //                Thread.Sleep(10);
        //            }
        //        }
        //        catch (Exception e)
        //        {
        //            Console.WriteLine(e.StackTrace + e.Message);
        //        }
        //    }
        //}

        /// <summary>
        /// 连接客户端的异步回调委托
        /// </summary>
        /// <param name="iar"></param>
        private void CallbackAccept(IAsyncResult iar)
        {
            Socket server = null;
            try
            {
                server = (Socket)iar.AsyncState;
                Socket client = server.EndAccept(iar);
                if (client != null)
                {
                    connectCount++;
                    string[] str = Convert.ToString(client.RemoteEndPoint).Split(new char[] { ':' });
                    log.Info(DateTime.Now.ToString() + ": TCP server has been connected to ." + str[0]);

                    //根据ip将客户端信息存入客户端字典,以及新建包序的字典
                    //断开不会remove，新进来后直接覆盖
                    if (!clientDic.ContainsKey(str[0]))
                    {
                        clientDic.TryAdd(str[0], client);
                        preSeq.TryAdd(str[0], -1);
                        currSeq.TryAdd(str[0], -1);
                    }
                    else
                    {
                        clientDic[str[0]] = client;
                        preSeq[str[0]] = -1;
                        currSeq[str[0]] = -1;
                    }
                    //str[0]是当前客户端的IP地址
                    if (!queSendDic.ContainsKey(str[0]))
                    {   //如果是新连接，初始化各种队列，发送队列，接受队列  
                        queSendDic.TryAdd(str[0], new ConcurrentQueue<SendInfo>());
                        isOverDelayDic.TryAdd(str[0], false);
                        timerConnectDic.TryAdd(str[0], null);//接收超时定时器
                        timerNetContionDic.TryAdd(str[0], null);//网线重连定时器
                        analysicBufferModelDic.TryAdd(str[0], new AnalysicBufferModel(false));
                        isSendThreadOverDic.TryAdd(str[0], false);
                        //启动发送队列的循环监听
                        Thread tSent = new Thread(new ParameterizedThreadStart(SendMessage));
                        tSent.Start(str[0]); ;
                        ThreadPool.QueueUserWorkItem(new WaitCallback(SendMessage), str[0]);
                    }
                    else
                    {
                        //如果之前已经建立过连接了，则重新赋值
                        queSendDic[str[0]] = new ConcurrentQueue<SendInfo>();
                        analysicBufferModelDic[str[0]] = new AnalysicBufferModel(false);
                        if (isSendThreadOverDic[str[0]])
                        {
                            Console.WriteLine(str[0] + "  上一次连接中断，重新连接");
                            //启动发送队列的循环监听
                            Thread tSent = new Thread(new ParameterizedThreadStart(SendMessage));
                            tSent.Start(str[0]); ;
                        }
                    }

                    //将客户端Ip存入字典中
                    if (!timerConnectDic.ContainsKey(str[0]))
                    {
                        timerConnectDic.TryAdd(str[0], null);
                    }
                    ////定时器每隔10秒监控是否有客户端断开连接
                    if (timerConnectDic[str[0]] != null)
                    {
                        timerConnectDic[str[0]].Close();
                    }
                    //接收超时时间设置为5秒
                    timerConnectDic[str[0]] = new System.Timers.Timer(5000);
                    timerConnectDic[str[0]].Elapsed += (s, ela) =>
                    {
                        if (!isOverDelayDic[str[0]])
                        {
                            isOverDelayDic[str[0]] = true;//每隔5秒将超时状态设置为true                    
                        }
                        else
                        {
                            Console.WriteLine("延时导致的断开");
                            disConnectProcess(str[0]);//客户端断开后的处理
                        }
                    };
                    timerConnectDic[str[0]].AutoReset = true;
                    timerConnectDic[str[0]].Enabled = true;
                    timerConnectDic[str[0]].Start();


                    //卢瑶瑶处给打钩用的//把参数封装在类里面传给实际执行的方法,触发连接成功事件
                    ConnectEventArgs con = new ConnectEventArgs(str[0], "80", true);
                    OnNewConnect(con);

                    AsyncSocketState asyState = new AsyncSocketState(client);
                    asyState.id = connectCount;
                    asyState.RecvDataBuffer = new byte[BufferSize];
                    try
                    {
                        //开始接收数据
                        client.BeginReceive(asyState.RecvDataBuffer, 0, asyState.RecvDataBuffer.Length, SocketFlags.None, new AsyncCallback(HandleDataReceived), asyState);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.StackTrace + e.Message);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.StackTrace + e.Message);
            }
            ////监听下一个客户端连接请求
            if (server != null)
            {
                try
                {
                    //接受下一个请求
                    server.BeginAccept(new AsyncCallback(CallbackAccept), server);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.StackTrace + e.Message);
                }
            }
        }
        /// <summary>
        /// 对出队的状态包分类进行处理
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="recv"></param>
        /// <param name="ip"></param>
        public void ProcessData(byte[] bytes, string recv, string ip)
        {
            switch (Convert.ToInt32(recv))
            {
                //如果是状态上传数据包
                case 720:
                    {
                        ////解析包序
                        currSeq[ip] = BitConverter.ToUInt16(bytes, 718);
                        if (preSeq[ip] != -1)
                        {
                            //包序间隔
                            ushort span = (ushort)(currSeq[ip] - preSeq[ip]);
                            //若丢包超过5个，则关机并弹窗提醒
                            if (span > 5)
                            {
                                Console.WriteLine(ip + "丢包----目前包序是：" + currSeq[ip] + "  之前包序是：" + preSeq[ip]);
                                //realid为设备编号，-1表示所有通道都关机
                                OnUserClose(-1, ip, false);
                            }
                        }
                        preSeq[ip] = currSeq[ip];


                        if (bytes[0] == 0xAA && bytes[1] == 0x55 && bytes[3] == 0x80)
                        {
                            try
                            {
                                //触发状态包处理事件
                                OnReceiveChannelData(bytes, ip);
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e.StackTrace + e.Message);
                            }

                            //处理故障
                            StateBag stateBag = new StateBag(bytes, Convert.ToInt32(recv), ip, clientDic[ip]);
                            ThreadPool.QueueUserWorkItem(new WaitCallback(TcpControl.RecordError), stateBag);
                            for (int i = 0; i < 8; i++)
                            {
                                if (isCloseJudge[i])
                                {
                                    int count = 0;
                                    ChannelState cs = ChannelStateControl.byte2Channel(bytes, i, 76);
                                    if (cs.DCstate2_Contactor == true || cs.ACstate2_AC_breakState == true)
                                    {
                                        count++;
                                    }
                                    //如果是并联通道，则需要判断其所有并联通道组内的通道是否分闸
                                    if (isChannelParalle[i])
                                    {
                                        int paraId = MutiChlHelper.GetParaIdByGidCid(ip, cs.GID + 1, cs.MID + 1, i + 1);
                                        List<int> ParallelList = MutiChlHelper.GetChlById(paraId, ip, cs.GID + 1, cs.MID + 1);
                                        //并联模式，解析所有并联组中的通道数据，判断分闸
                                        for (int j = 1; j < ParallelList.Count; j++)
                                        {
                                            ChannelState paChlState = ChannelStateControl.byte2Channel(bytes, ParallelList[j] - 1, 76);
                                            if (paChlState.DCstate2_Contactor == true)
                                            {
                                                count++;
                                            }
                                        }
                                    }
                                    if (count == 0)
                                    {
                                        isClosed[i] = true;
                                        isCloseJudge[i] = false;
                                        //发关机撤回指令
                                        if (!isChannelParalle[i])
                                        {
                                            inAction = StepRunControl.IndependentCloseBack(inAction, temp, clientDic[ip]);
                                        }
                                        else
                                        {
                                            paAction = StepRunControl.ParalleCloseBack(paAction, temp, clientDic[ip]);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                case 16:
                    {
                        if (bytes[3] == 0x81 || bytes[3] == 0x82)
                        {
                            CondiRequest condiReq = ChannelStateControl.byte2CondiRequest(bytes, 14);
                            OnReceiveCondiRequest(condiReq, ip);
                        }
                        else if (bytes[3] == 0x83 || bytes[3] == 0x84)
                        {

                        }
                    }
                    break;
                //case 0:
                //    {
                //        CloseConnectEventArgs con = new CloseConnectEventArgs(ip, "BTS80", false);
                //        OnCloseConnect(con);
                //        queSendDic.Remove(ip);
                //        queReceiveDic.Remove(ip);
                //        clientDic[ip] = null;
                //    }
                //    break;
            }
        }
        /// <summary>
        /// 接收数据的异步回调委托
        /// </summary>
        /// <param name="ar"></param>
        private void HandleDataReceived(IAsyncResult ar)
        {
            try
            {
                AsyncSocketState asyState = (AsyncSocketState)ar.AsyncState;
                Socket client = asyState.ClientSocket;
                string[] str = Convert.ToString(asyState.ClientSocket.RemoteEndPoint).Split(new char[] { ':' });
                string ip = str[0];

                if (clientDic[ip] != null)
                {
                    try
                    {
                        //完成数据接收，recv为接收到字节
                        int recv = client.EndReceive(ar);
                        isOverDelayDic[ip] = false;//将超时状态设置为false
                        //将接受缓存区的数据读出赋值给bufferData数组
                        byte[] bufferData = new byte[recv];
                        Array.Copy(asyState.RecvDataBuffer, bufferData, recv);                 
                        //如果包长为720，直接入队
                        if (recv == 720)
                        {
                            ProcessData(bufferData, "720", ip);
                        }
                        //否则进行解析
                        else
                        {
                            SplitSingleBag(bufferData, recv, ip, analysicBufferModelDic[ip], asyState.id);
                        }
                    }
                    catch (SocketException e)
                    {
                        Console.WriteLine(e.StackTrace + e.Message+e.ErrorCode);
                        Console.WriteLine("异常导致的断开");
                        //断开连接时触发的事件
                        disConnectProcess(ip);
                    }
                    finally
                    {
                        if (clientDic[ip] != null)
                        {
                            try
                            {
                                //接收下一条数据                               
                                client.BeginReceive(asyState.RecvDataBuffer, 0, asyState.RecvDataBuffer.Length, SocketFlags.None,
                                    new AsyncCallback(HandleDataReceived), asyState);
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e.StackTrace + e.Message);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.StackTrace + e.Message);
            }
        }
        /// <summary>
        /// 关机流程
        /// </summary>
        /// <param name="cid"></param>
        public void ClosingJudge(string ip, int cid, int stepNum, int gid, CommandProtocol.IndependAction inAction, CommandProtocol.ParalleAction paAction, bool isParalle)
        {
            this.inAction = inAction;
            this.paAction = paAction;
            isClosed[cid] = false;
            isCloseJudge[cid] = true;
            isChannelParalle[cid] = isParalle;
            System.Timers.Timer timeSpan = new System.Timers.Timer(10000);
            timeSpan.Elapsed += (s, ela) =>
            {
                //如果没关机成功，每隔10s重新发送一次关机指令
                if (!isClosed[cid])
                {
                    if (!isParalle)
                    {
                        this.inAction = StepRunControl.IndependentClose(inAction, temp, clientDic[ip]);
                    }
                    else
                    {
                        this.paAction = StepRunControl.ParalleClose(paAction, temp, clientDic[ip]);
                    }
                }
                else
                {
                    timeSpan.Close();
                }
            };
            timeSpan.AutoReset = true;
            timeSpan.Enabled = true;
            timeSpan.Start();
        }

        /// <summary>
        /// 客户端断开执行的操作
        /// </summary>
        /// <param name="ip"></param>
        private void disConnectProcess(string ip)
        {
            //断开连接时触发的事件
            CloseConnectEventArgs closeConnect = new CloseConnectEventArgs(ip, "BTS80", false);
            OnCloseConnect(closeConnect);//断开连接
            OnNetClose(ip);//网络断开更新通道状态
            ThreadPool.QueueUserWorkItem(new WaitCallback(TcpControl.ConnectShowMsg), ip);
            clientDic[ip] = null;
            queSendDic[ip] = null;
            Console.WriteLine(ip + "   通信故障时间:" + System.DateTime.Now.ToString("HH:mm:ss.fff"));
            //开启定时器监听是否有网线接入
            timerNetContionDic[ip] = new System.Timers.Timer(10000);
            timerNetContionDic[ip].Elapsed += (newS, newEla) =>
            {
                //尝试ping网线的ip地址
                if (PingNetAddress(ip))//将当前连入网线的ip地址赋予strNetAdd,以便判断网线是否重新连接
                {
                    AutoConControl.BeginBroadcast();//做一次自动组网
                    timerNetContionDic[ip].Close();//关闭网络重连定时器
                }
            };
            timerNetContionDic[ip].AutoReset = true;
            timerNetContionDic[ip].Enabled = true;
            timerNetContionDic[ip].Start();
            timerConnectDic[ip].Close();//关闭超时检测定时器
        }

        /// <summary>
        /// ping ip地址能否ping通
        /// </summary>
        /// <returns></returns>
        private bool PingNetAddress(string strNetAdd)
        {
            bool Flage = false;
            Ping ping = new Ping();
            try
            {
                PingReply pr = ping.Send(strNetAdd, 3000);
                if (pr.Status == IPStatus.TimedOut)
                {
                    Flage = false;
                }
                if (pr.Status == IPStatus.Success)
                {
                    Flage = true;
                }
                else
                {
                    Flage = false;
                }
            }
            catch
            {
                Flage = false;
            }
            return Flage;
        }
        /// <summary>
        /// 拆包算法
        /// </summary>
        /// <param name="bufferData"></param>
        /// <param name="recv"></param>
        /// <param name="ip"></param>
        /// <param name="anaBufferModel"></param>
        /// <param name="id"></param>
        private void SplitSingleBag(byte[] bufferData, int recv, string ip, AnalysicBufferModel anaBufferModel, int id)
        {
            int head = 0;//定义一个指针
            //如果上一个缓冲区不是满的，包已经被取完,则从头开始读缓冲区
            if (!anaBufferModel.isFull)
            {
                if (recv == 720)//当recv刚好是720，则直接入队
                {
                    byte[] minBufferData = new byte[720];
                    Array.ConstrainedCopy(bufferData, head, minBufferData, 0, 720);
                    ProcessData(minBufferData, "720", ip);
                    //Console.WriteLine("1-ip:" + ip + "入队的包序：  " + BitConverter.ToUInt16(minBufferData, 718));
                }
                else if (recv == 16)////当recv刚好是16，则直接入队
                {
                    byte[] minBufferData = new byte[16];
                    Array.ConstrainedCopy(bufferData, head, minBufferData, 0, 16);
                    ProcessData(minBufferData, "16", ip);
                    //Console.WriteLine("入队16包1：  ");
                }
                else//循环遍历
                {
                    TravelBuffer(bufferData, ip, head, recv, anaBufferModel, id);
                }
            }
            else//如果上一个缓冲区是满的，则需要根据上一个缓冲区最后一个包的情况先进行相应的合并操作
            {
                int lastLength = anaBufferModel.lastBag.Length;
                //将两个数组合并为一个数组
                byte[] newBufferData = new byte[lastLength + bufferData.Length];
                anaBufferModel.lastBag.CopyTo(newBufferData, 0);
                bufferData.CopyTo(newBufferData, lastLength);
                if (BitConverter.ToUInt16(newBufferData, head + 10) == 706)
                {
                    byte[] minBufferData = new byte[720];
                    if (newBufferData.Length >= 720)
                    {
                        Array.ConstrainedCopy(newBufferData, head, minBufferData, 0, 720);
                        head += 720;
                        ProcessData(minBufferData, "720", ip);
                    }
                }
                //假如此时遍历读取的包是16包
                else if (BitConverter.ToUInt16(newBufferData, head + 10) == 2)
                {
                    byte[] minBufferData = new byte[16];
                    if (newBufferData.Length >= 16)
                    {
                        Array.ConstrainedCopy(newBufferData, head, minBufferData, 0, 16);
                        head += 16;
                        ProcessData(minBufferData, "16", ip);
                        //Console.WriteLine("入队16包2：  ");
                    }
                }
                //循环遍历缓冲区剩余的所有数据
                TravelBuffer(newBufferData, ip, head, recv + lastLength, anaBufferModel, id);
            }
        }

        /// <summary>
        /// 循环遍历缓冲区数据,进行拆包rivate
        /// </summary>
        /// <param name="bufferData"></param>
        /// <param name="ip"></param>
        /// <param name="head"></param>
        /// <param name="recv"></param>
        /// <param name="anaBufferModel"></param>
        /// <param name="queReceiveDic"></param>
        private void TravelBuffer(byte[] bufferData, string ip, int head, int recv, AnalysicBufferModel anaBufferModel, int id)
        {
            bool flag = false;//用来标志缓冲区已满并且末尾数据不完整，为false表示缓冲区未满或者缓冲区满了但是数据刚好完整，为true表示缓冲区已满并且末尾数据不完整。
            while (head < recv)
            {
                int diff = recv - head;//剩余数据量
                if (diff >= 720)
                {
                    //假如此时遍历读取的包是720包
                    if (BitConverter.ToUInt16(bufferData, head + 10) == 706)
                    {
                        byte[] minBufferData = new byte[720];
                        Array.ConstrainedCopy(bufferData, head, minBufferData, 0, 720);
                        head += 720;
                        ProcessData(minBufferData, "720", ip);
                    }
                    //假如此时遍历读取的包是16包
                    else if (BitConverter.ToUInt16(bufferData, head + 10) == 2)
                    {
                        byte[] minBufferData = new byte[16];
                        Array.ConstrainedCopy(bufferData, head, minBufferData, 0, 16);
                        head += 16;
                        ProcessData(minBufferData, "16", ip);
                        //Console.WriteLine("入队16包3：  ");
                    }
                }
                else if ((diff >= 16) && (diff < 720))
                {
                    //假如此时遍历读取的包是720包,但是由于剩下的数据量不足720，则需要先将剩余的字节保存，与下一个缓冲区前面剩余的部分合并为一个包
                    if (BitConverter.ToUInt16(bufferData, head + 10) == 706)
                    {
                        byte[] minBufferData = new byte[diff];
                        Array.ConstrainedCopy(bufferData, head, minBufferData, 0, diff);
                        anaBufferModel.lastBagType = 720;
                        anaBufferModel.lastBag = minBufferData;
                        anaBufferModel.isFull = true;
                        flag = true;
                        break;
                    }
                    //假如此时遍历读取的包是16包
                    else if (BitConverter.ToUInt16(bufferData, head + 10) == 2)
                    {
                        byte[] minBufferData = new byte[16];
                        Array.ConstrainedCopy(bufferData, head, minBufferData, 0, 16);
                        head += 16;
                        ProcessData(minBufferData, "16", ip);
                        //Console.WriteLine("入队16包4：  ");
                    }
                }
                else if (diff < 16)
                {
                    byte[] minBufferData = new byte[diff];
                    Array.ConstrainedCopy(bufferData, head, minBufferData, 0, diff);
                    anaBufferModel.lastBagType = 0;//未知类型
                    anaBufferModel.lastBag = minBufferData;
                    anaBufferModel.isFull = true;
                    flag = true;
                    break;
                }

            }
            //如果缓冲区未满或者缓冲区刚好满了但是数据完整，则将isFull置为false
            if (!flag)
            {
                anaBufferModel.isFull = false;
            }
        }
    }
}
